package com.feicheng.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feicheng.common.constant.Constant;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.message.SystemMessage;
import com.feicheng.common.result.ResultInfo;
import com.feicheng.persistence.entity.*;
import com.feicheng.persistence.service.*;
import com.feicheng.service.BaseService;
import com.feicheng.service.IFSystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

@Service
public class FShopSystemServiceImpl extends BaseService implements IFSystemService {

    @Autowired
    IStoreUserService iUserService;

    @Autowired
    IStoreRoleService iRoleService;

    @Autowired
    IStorePermissionService iPermissionService;

    @Autowired
    IStoreUserRoleService iUserRoleService;

    @Autowired
    IStoreRolePermissionService iRolePermissionService;

    @Autowired
    IStoreUserInfoService iStoreUserInfoService;

    @Autowired
    SystemMessage systemMessage;

    /**
     * @see com.feicheng.service.IFSystemService#selectUser(Integer, Integer, String, String, String)
     */
    @Override
    public ResultInfo selectUser(Integer currentPage, Integer pageSize, String account, String tel, String secId, Integer storeId) {

    	
    	JSONArray userIds = new JSONArray();
    	if (null != storeId) {
    		QueryWrapper<StoreUserInfo> storeUserInfoWrapper = new QueryWrapper<>();
    		storeUserInfoWrapper.eq(Constant.ENTITY.STORE_USER_INFO.STORE_ID, storeId);
    		List<StoreUserInfo> storeUserInfos = iStoreUserInfoService.list(storeUserInfoWrapper);
    		if (null != storeUserInfos && storeUserInfos.size() > 0) {
    			for (StoreUserInfo storeUserInfo : storeUserInfos) {
    				userIds.add(storeUserInfo.getUserId());
    			}
    		}
    	}

        // 构建查询条件
        QueryWrapper<StoreUser> userWrapper = new QueryWrapper<StoreUser>();
        
        if (userIds.size() > 0) {
        	userWrapper.in(Constant.ENTITY.STORE_USER.USER_ID, userIds);
        }
        
        // 如果账号不是空把账号加入查询的条件中
        if (StringUtils.hasLength(account)) {
            userWrapper.like(Constant.ENTITY.STORE_USER.ACCOUNT, account);
        }
        // 如果电话号码不是空把电话号码加入到查询的条件中
        if (StringUtils.hasLength(tel)) {
            userWrapper.like(Constant.ENTITY.STORE_USER.TEL, tel);
        }
        // 如果身份证号码不是空把身份证号码加入到查询条件中
        if (StringUtils.hasLength(secId)) {
            userWrapper.like(Constant.ENTITY.STORE_USER.SEC_ID, secId);
        }

        // 创建分页查询
        IPage<StoreUser> pageInfo = new Page<StoreUser>(currentPage, pageSize);
        // 返回查询结果
        return ResultInfo.success(iUserService.page(pageInfo, userWrapper));

    }

    @Override
    public ResultInfo selectUserByAccount(String account) {
        return null;
    }

    /**
     * @see com.feicheng.service.IFSystemService#selectUserById(Integer)
     */
    @Override
    public ResultInfo selectUserById(Integer userId) {
        // 校验用户ID
        if (null == userId) {
            throw new SystemException(systemMessage.getE01());
        }

        // 根据主键id查询
        StoreUser user = iUserService.getById(userId);

        JSONObject result = new JSONObject();
        result.put(Constant.RESULT.USER.USER, user);


        // 构建查询条件
        QueryWrapper<StoreUserRole> userRoleWrapper = new QueryWrapper<StoreUserRole>();
        userRoleWrapper.eq(Constant.ENTITY.STORE_USER.USER_ID, userId);

        // 执行查询
        List<StoreUserRole> userRoles = iUserRoleService.list(userRoleWrapper);

        // 将取得取得的角色ID保存到角色ID集合中
        Set<Integer> roleIds = new HashSet<Integer>();
        for (StoreUserRole ur : userRoles) {
            roleIds.add(ur.getRoleId());
        }

        if (roleIds.size() > 0) {

            /* 构建角色查询 */
            QueryWrapper<StoreRole> roleWrapper = new QueryWrapper<StoreRole>();
            roleWrapper.in(Constant.ENTITY.STORE_ROLE.ROLE_ID, roleIds);
            List<StoreRole> roles = iRoleService.list(roleWrapper);
            result.put(Constant.RESULT.ROLE.ROLES, roles);

            // 构建角色ID查询条件
            QueryWrapper<StoreRolePermission> rolePermissionWrapper =
                    new QueryWrapper<StoreRolePermission>();
            rolePermissionWrapper.in(Constant.ENTITY.STORE_ROLE.ROLE_ID, roleIds);

            // 执行权限ID查询
            List<StoreRolePermission> rolePermissions =
                    iRolePermissionService.list(rolePermissionWrapper);

            // 将取得的权限ID保存到权限ID集合中
            Set<Integer> permissionIds = new HashSet<Integer>();
            for (StoreRolePermission rp : rolePermissions) {
                permissionIds.add(rp.getPermissionId());
            }

            if (permissionIds.size() > 0) {
                QueryWrapper<StorePermission> permissionWrapper = new QueryWrapper<StorePermission>();
                if (!permissionIds.isEmpty()) {
                    permissionWrapper.in(Constant.ENTITY.STORE_PERMISSION.PERMISSION_ID, permissionIds);
                }
                permissionWrapper.orderByAsc(Constant.ENTITY.STORE_PERMISSION.P_ID);

                // 执行权限查询
                List<StorePermission> permissions = iPermissionService.list(permissionWrapper);
                result.put(Constant.RESULT.PERMISSION.PERMISSIONS, permissions);
            }
        }
        // 返回查询到的用户信息
        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#addUser(User, String)
     */
    @Override
    @Transactional
    public ResultInfo addUser(User user, String roles) {

        /* 校验用户信息 */
        if (!StringUtils.hasLength(user.getAccount())
                || !StringUtils.hasLength(user.getPassword())
                || !StringUtils.hasLength(user.getTel())
                || !StringUtils.hasLength(user.getSecId())) {
            throw new SystemException(systemMessage.getE02());
        }

        /* 校验用户角色信息 */
        if (!StringUtils.hasLength(roles)) {
            throw new SystemException(systemMessage.getE03());
        }

        /* 在session中获取当前用户的userId */
        int currentUserId = super.currentUser().getUserId();
        int currentStoreId = super.currentStore().getStoreId();

        /* 设置用户信息完成新增 */
        user.setOpenId("");
        user.setCu(currentUserId);
        user.setUu(currentUserId);
        user.setCt(super.ct(true));
        user.setUt(super.ct());
        StoreUser u = (StoreUser) user;
        iUserService.save(u);

        /* 设置用户角色信息完成新增 */
        JSONArray rolesIdArray = JSONArray.parseArray(roles);
        List<StoreUserRole> roleList = new ArrayList<StoreUserRole>();
        for (int i = 0; i < rolesIdArray.size(); i++) {
            Integer roleId = Integer.parseInt((String) rolesIdArray.get(i));
            StoreUserRole userRole = new StoreUserRole();
            userRole.setUserId(u.getUserId());
            userRole.setRoleId(roleId);
            roleList.add(userRole);
        }
        iUserRoleService.saveBatch(roleList);

        StoreUserInfo sui = new StoreUserInfo();
        sui.setStoreId(currentStoreId);
        sui.setUserId(u.getUserId());
        iStoreUserInfoService.save(sui);

        // 返回执行结果
        return ResultInfo.success(user);
    }

    /**
     * @see com.feicheng.service.IFSystemService#updateUser(User, String)
     */
    @Override
    @Transactional
    public ResultInfo updateUser(User user, String roles) {

        /* 校验用户主键 */
        if (null == user.getUserId()) {
            throw new SystemException(systemMessage.getE01());
        }

        /* 在session中获取当前用户的userId */
        int currentUserId = super.currentUser().getUserId();
        user.setUu(currentUserId);
        user.setUt(LocalDateTime.now());
        // 修改用户信息
        StoreUser su = (StoreUser) user;
        iUserService.updateById(su);

        /* 通过userId删除user和role的关联 */
        if (StringUtils.hasLength(roles)) {
            QueryWrapper<StoreUserRole> removeWrapper = new QueryWrapper<StoreUserRole>();
            removeWrapper.eq(Constant.ENTITY.STORE_USER.USER_ID, user.getUserId());
            iUserRoleService.remove(removeWrapper);

            // 新增user与role的关联
            JSONArray rolesIdArray = JSONArray.parseArray(roles);
            List<StoreUserRole> roleList = new ArrayList<StoreUserRole>();
            for (int i = 0; i < rolesIdArray.size(); i++) {
                Integer roleId = (Integer) rolesIdArray.get(i);
                StoreUserRole userRole = new StoreUserRole();
                userRole.setUserId(user.getUserId());
                userRole.setRoleId(roleId);
                roleList.add(userRole);
            }
            iUserRoleService.saveBatch(roleList);
        }

        // 返回更新结果
        return ResultInfo.success(user);
    }

    /**
     * @see com.feicheng.service.IFSystemService#deleteUser(Integer)
     */
    @Override
    @Transactional
    public ResultInfo deleteUser(Integer userId) {
        /* 校验用户主键 */
        if (null == userId) {
            throw new SystemException(systemMessage.getE01());
        }

        /* 删除用户角色信息 */
        QueryWrapper<StoreUserRole> deleteWrapper = new QueryWrapper<StoreUserRole>();
        deleteWrapper.eq(Constant.ENTITY.STORE_USER.USER_ID, userId);
        iUserRoleService.remove(deleteWrapper);

        QueryWrapper<StoreUserInfo> deleteSUIWrapper = new QueryWrapper<StoreUserInfo>();
        deleteSUIWrapper.eq(Constant.ENTITY.STORE_USER.USER_ID, userId);
        iStoreUserInfoService.remove(deleteSUIWrapper);

        /* 删除用户信息 */
        iUserService.removeById(userId);

        // 返回删除结果
        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService
     */
    @Override
    public ResultInfo selectRoles(String roleName, Boolean statu, Integer currentPage, Integer pageSize) {
        QueryWrapper<StoreRole> roleQueryWapper = new QueryWrapper<StoreRole>();

        if (StringUtils.hasLength(roleName)) {
            roleQueryWapper.like(Constant.ENTITY.STORE_ROLE.ROLE_NAME, roleName);
        }

        if (statu != null) {
            roleQueryWapper.eq(Constant.ENTITY.STORE_ROLE.STATU, statu);
        }

        IPage<StoreRole> pageInfo = new Page<StoreRole>(currentPage, pageSize);
        return ResultInfo.success(iRoleService.page(pageInfo, roleQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#allRoles(Boolean)
     */
    @Override
    public ResultInfo allRoles(Boolean statu) {
        QueryWrapper<StoreRole> roleQueryWapper = new QueryWrapper<StoreRole>();
        roleQueryWapper.eq(Constant.ENTITY.STORE_ROLE.STATU, statu);
        return ResultInfo.success(iRoleService.list(roleQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#getRoleById(Integer)
     */
    @Override
    public ResultInfo getRoleById(Integer roleId) {
        if (null == roleId) {
            throw new SystemException(systemMessage.getE04());
        }

        StoreRole role = iRoleService.getById(roleId);

        if (null == role) {
            throw new SystemException(systemMessage.getE07());
        }

        JSONObject result = new JSONObject();
        result.put(Constant.RESULT.ROLE.ROLE, role);

        QueryWrapper<StoreRolePermission> rpWrapper = new QueryWrapper<StoreRolePermission>();
        rpWrapper.eq(Constant.ENTITY.STORE_ROLE.ROLE_ID, roleId);
        List<StoreRolePermission> rpList = iRolePermissionService.list(rpWrapper);
        if (null != rpList && !rpList.isEmpty()) {
            List<Integer> permissionIds = new ArrayList<Integer>();
            for (StoreRolePermission rp : rpList) {
                permissionIds.add(rp.getPermissionId());
            }
            result.put(Constant.RESULT.PERMISSION.PERMISSIONS, permissionIds);
        }

        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#addRole(Role, String)
     */
    @Override
    @Transactional
    public ResultInfo addRole(Role role, String permissions) {
        if (null != role.getRoleId()) {
            throw new SystemException(systemMessage.getE05());
        }
        // 在session中获取userId
        int currentUserId = super.currentUser().getUserId();
        role.setCu(currentUserId);
        role.setUu(currentUserId);
        role.setCt(super.ct(true));
        role.setUt(super.ct());
        role.setStatu(true);
        StoreRole sr = (StoreRole) role;
        iRoleService.save(sr);

        if (null == role.getRoleId()) {
            throw new SystemException(systemMessage.getE06());
        }

        if (JSONValidator.from(permissions).validate()) {
            JSONArray permissionIds = JSON.parseArray(permissions);
            if (!permissionIds.isEmpty()) {
                QueryWrapper<StoreRolePermission> rpWrapper = new QueryWrapper<StoreRolePermission>();
                rpWrapper.eq(Constant.ENTITY.STORE_ROLE.ROLE_ID, role.getRoleId());
                iRolePermissionService.remove(rpWrapper);
                List<StoreRolePermission> batchList = new ArrayList<StoreRolePermission>();
                for (Object permissionId : permissionIds) {
                    StoreRolePermission rm = new StoreRolePermission();
                    rm.setRoleId(role.getRoleId());
                    rm.setPermissionId((Integer) permissionId);
                    batchList.add(rm);
                }
                iRolePermissionService.saveBatch(batchList);
            }
        }

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#updateRole(Role, String)
     */
    @Override
    @Transactional
    public ResultInfo updateRole(Role role, String permissions) {
        if (null == role.getRoleId()) {
            throw new SystemException(systemMessage.getE04());
        }
        StoreRole sr = (StoreRole) role;
        iRoleService.updateById(sr);

        if (JSONValidator.from(permissions).validate()) {

            JSONArray permissionIds = JSON.parseArray(permissions);
            if (!permissionIds.isEmpty()) {
                QueryWrapper<StoreRolePermission> rpWrapper = new QueryWrapper<StoreRolePermission>();
                rpWrapper.eq(Constant.ENTITY.STORE_ROLE_PERMISSION.ROLE_ID, role.getRoleId());
                iRolePermissionService.remove(rpWrapper);

                List<StoreRolePermission> batchList = new ArrayList<StoreRolePermission>();
                for (Object permissionId : permissionIds) {
                    StoreRolePermission rm = new StoreRolePermission();
                    rm.setRoleId(role.getRoleId());
                    rm.setPermissionId((Integer) permissionId);
                    batchList.add(rm);
                }
                iRolePermissionService.saveBatch(batchList);
            }
        }

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#deleteRole(Integer)
     */
    @Override
    @Transactional
    public ResultInfo deleteRole(Integer roleId) {
        if (null == roleId) {
            throw new SystemException(systemMessage.getE04());
        }

        QueryWrapper<StoreRolePermission> rpWrapper = new QueryWrapper<StoreRolePermission>();
        rpWrapper.eq(Constant.ENTITY.STORE_ROLE.ROLE_ID, roleId);
        iRolePermissionService.remove(rpWrapper);
        iRoleService.removeById(roleId);
        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#getPermissions(String, String, Boolean, Integer, Integer, Integer)
     */
    @Override
    public ResultInfo getPermissions(String name, String path, Boolean statu, Integer pId, Integer currentPage, Integer pageSize) {
        QueryWrapper<StorePermission> permissionQueryWapper = new QueryWrapper<StorePermission>();

        if (StringUtils.hasLength(name)) {
            permissionQueryWapper.like(Constant.ENTITY.STORE_PERMISSION.NAME, name);
        }

        if (StringUtils.hasLength(path)) {
            permissionQueryWapper.like(Constant.ENTITY.STORE_PERMISSION.PATH, path);
        }

        if (null != statu) {
            permissionQueryWapper.eq(Constant.ENTITY.STORE_PERMISSION.STATU, statu);
        }

        if (null != pId) {
            permissionQueryWapper.eq(Constant.ENTITY.STORE_PERMISSION.P_ID, pId);
        }

        IPage<StorePermission> pageInfo = new Page<StorePermission>(currentPage, pageSize);
        return ResultInfo.success(iPermissionService.page(pageInfo, permissionQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#allPermissions(Boolean, Integer)
     */
    @Override
    public ResultInfo allPermissions(Boolean statu, Integer pId) {

        QueryWrapper<StorePermission> permissionQueryWrapper = new QueryWrapper<StorePermission>();
        if (null != statu) {
            permissionQueryWrapper.eq(Constant.ENTITY.STORE_PERMISSION.STATU, statu);
        }

        if (null != pId) {
            permissionQueryWrapper.eq(Constant.ENTITY.STORE_PERMISSION.P_ID, pId);
        }

        List<StorePermission> allList = iPermissionService.list(permissionQueryWrapper);
        List<StorePermission> result = new ArrayList<StorePermission>();
        Map<Integer, StorePermission> pMap = new HashMap<Integer, StorePermission>();
        for (StorePermission p : allList) {
            if (0 == p.getPId()) {
                pMap.put(p.getPermissionId(), p);
                result.add(p);
            }
        }

        for (StorePermission p : allList) {
            if (0 != p.getPId()) {
                StorePermission fP = pMap.get(p.getPId());

                if (fP.getPermissions() == null) {
                    fP.setPermissions(new ArrayList<Permission>());
                }

                fP.getPermissions().add(p);
            }
        }
        pMap.clear();
        pMap = null;
        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#getPermission(Integer)
     */
    @Override
    public ResultInfo getPermission(Integer permissionId) {
        if (null == permissionId) {
            throw new SystemException(systemMessage.getE08());
        }

        return ResultInfo.success(iPermissionService.getById(permissionId));
    }

    /**
     * @see com.feicheng.service.IFSystemService#addPermission(Permission)
     */
    @Override
    public ResultInfo addPermission(Permission permission) {
        if (null != permission.getPermissionId()) {
            throw new SystemException(systemMessage.getE08());
        }

        if (!StringUtils.hasLength(permission.getName())) {
            throw new SystemException(systemMessage.getE09());
        }

        if (null == permission.getPId()) {
            throw new SystemException(systemMessage.getE10());
        } else if (0 == permission.getPId()) {
            permission.setPath("");
        } else {
            if (!StringUtils.hasLength(permission.getPath())) {
                throw new SystemException(systemMessage.getE11());
            }
        }

        int currentUserId = super.currentUser().getUserId();
        permission.setCu(currentUserId);
        permission.setCt(LocalDateTime.now());
        permission.setUu(currentUserId);
        permission.setUt(LocalDateTime.now());
        permission.setStatu(true);
        StorePermission sp = (StorePermission) permission;
        iPermissionService.save(sp);

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#updatePermission(Permission)
     */
    @Override
    public ResultInfo updatePermission(Permission pp) {

        StorePermission permission = (StorePermission) pp;

        if (null == permission.getPermissionId()) {
            throw new SystemException(systemMessage.getE08());
        }

        permission.setCu(null);
        permission.setCt(null);

        int currentUserId = super.currentUser().getUserId();

        permission.setUu(currentUserId);
        permission.setUt(super.ct(true));

        if (null == permission.getPId()) {
            throw new SystemException(systemMessage.getE10());
        } else if (0 == permission.getPId()) {
            permission.setPath("");
        } else {
            if (!StringUtils.hasLength(permission.getPath())) {
                throw new SystemException(systemMessage.getE11());
            }
        }

        iPermissionService.updateById(permission);

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#deletePermission(Integer)
     */
    @Override
    @Transactional
    public ResultInfo deletePermission(Integer permissionId) {
        if (null == permissionId) {
            throw new SystemException(systemMessage.getE08());
        }

        QueryWrapper<StoreRolePermission> rpWrapper = new QueryWrapper<StoreRolePermission>();
        rpWrapper.eq(Constant.ENTITY.STORE_PERMISSION.PERMISSION_ID, permissionId);
        iRolePermissionService.remove(rpWrapper);
        iPermissionService.removeById(permissionId);

        return ResultInfo.success();
    }
}
